﻿// <copyright file="Program.cs" company="N/A">
//     Copyright (c) Nicholas Barrett and Benjamin Kasten.  All rights reserved.
//
//     This program is free software; you can redistribute it and/or modify it
//     under the terms of the GNU General Public License as published by the
//     Free Software Foundation; either version 2 of the License, or (at your
//     option) any later version.
//
//     This program is distributed in the hope that it will be useful, but
//     WITHOUT ANY WARRANTY; without even the implied warranty of
//     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
//     Public License for more details.
//
//     You should have received a copy of the GNU General Public License along
//     with this program; if not, write to the Free Software Foundation, 
//     Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
// </copyright>

namespace BetterAzureTableStorage.Demo
{
    using System;
    using System.Collections.Generic;
    using System.Data.Services.Client;
    using System.Linq;
    using System.Text;
    using BetterAzureTableStorage;
    using Microsoft.WindowsAzure;

    /// <summary>
    /// Contains the entry point for the console application
    /// </summary>
    public class Program
    {
        /// <summary>
        /// Entry point for the console application
        /// </summary>
        /// <param name="args">The command line arguments.</param>
        internal static void Main(string[] args)
        {
            TTableStorageDataContext context = new TTableStorageDataContext(
                "http://ipv4.fiddler:10002/devstoreaccount1",
                CloudStorageAccount.DevelopmentStorageAccount.Credentials,
                GetTableStorageInfo);

            Console.WriteLine("Creating Vehicle Table");
            context.CreateTableIfNotExists("TVehicle");

            string partitionKey = Guid.NewGuid().ToString();

            TCar car1 = new TCar()
            {
                Fuel = 15.235,
                Make = "Saturn",
                Weight = 2409.42,
                Color = TColor.Orange,

                PartitionKey = partitionKey,
                RowKey = Guid.NewGuid().ToString(),
                Timestamp = DateTime.UtcNow
            };

            TBicycle bike1 = new TBicycle()
            {
                HasHandlebarBell = true,
                Make = "Husky",
                Weight = 38.1233,
                Color = TColor.Purple,

                PartitionKey = partitionKey,
                RowKey = Guid.NewGuid().ToString(),
                Timestamp = DateTime.UtcNow
            };

            Console.WriteLine(String.Format("Adding object({0}) to table storage context", car1));
            context.AddObject(car1);
            Console.WriteLine(String.Format("Adding object({0}) to table storage context", bike1));
            context.AddObject(bike1);

            for (int i = 0; i < 900; i++)
            {
                TBicycle bikex = new TBicycle()
                {
                    HasHandlebarBell = true,
                    Make = "Husky",
                    Weight = 38.1233,
                    Color = TColor.Purple,

                    PartitionKey = partitionKey,
                    RowKey = Guid.NewGuid().ToString(),
                    Timestamp = DateTime.UtcNow
                };
                context.AddObject(bikex);
            }

            Console.WriteLine("Saving changes in context to table storage");
            context.SaveChanges(SaveChangesOptions.None);

            Console.WriteLine("Querying table assigned for type {0} where entities have a PartitionKey = {1}", typeof(TVehicle), partitionKey);
            var qry = context.CreateQuery<TVehicle>().Where(v => v.PartitionKey == partitionKey && v.Make == "Husky");

            foreach (TVehicle vehicle in qry)
            {
                Console.WriteLine(vehicle.GetType().ToString());
            }

            Console.WriteLine("Finished.  Press any key.");
            Console.ReadKey();
        }

        /// <summary>
        /// Gets the table storage info.
        /// </summary>
        /// <param name="type">The type to return information about.</param>
        /// <returns>A new TTableStorageInfo based on information about the <paramref name="type"/></returns>
        internal static TTableStorageInfo GetTableStorageInfo(Type type)
        {
            TTableStorageInfo tableStorageInfo = new TTableStorageInfo()
            {
                ClassType = type,
                ConditionalValue = type.IsAbstract ? null : (int?)(type.GetCustomAttributes(typeof(TypeIdAttribute), false).First() as TypeIdAttribute).Discriminator,
                PropertyList = type.GetProperties().Select(prop => new TTablePropertyInfo(prop, prop.Name)).ToList(),
                TableName = type.IsAbstract ? type.Name : type.BaseType.Name
            };

            return tableStorageInfo;
        }
    }
}
